package com.wisecoach.gatewayplus.transaction.tx;

import com.wisecoach.gatewayplus.transaction.SubmitTxContext;
import com.wisecoach.util.CollectionUtils;
import org.hyperledger.fabric.client.SubmitException;
import org.hyperledger.fabric.client.SubmittedTransaction;

import java.util.List;

/**
 * {@code @author:} wisecoach
 * {@code @date:} 2023/6/16 上午1:30
 * {@code @version:} 1.0.0
 */
public class SubmitTxConsumer {

    private final SubmitTxResource resource;

    public SubmitTxConsumer(SubmitTxResource resource) {
        this.resource = resource;
    }

    /**
     * 所有方法执行成功后，消费待提交的交易
     * 弹出一层递归，如果是第0层，则说明需要提交期间累计的交易，提交后需要将交易id放入到需要确认的交易队列中
     */
    public void consumeOnReturn() {
        // 弹出一层递归，如果等于0才需要提交
        resource.pop();
        if (resource.getStack() == 0) {
            List<SubmitTxContext> txsToCommit = resource.getTxsToCommit();
            if (!CollectionUtils.isEmpty(txsToCommit)) {
                txsToCommit.forEach(ctx -> {
                    try {
                        SubmittedTransaction submittedTransaction = ctx.getTransaction().submitAsync();
                        ctx.setSubmittedTransaction(submittedTransaction);
                        resource.pushTxToConfirm(ctx);
                    } catch (SubmitException e) {
                        throw new RuntimeException(e);
                    }
                });
                resource.clearTxsToCommit();
            }
        }
    }

    /**
     * 当方法执行失败后消费待提交的事务
     * 如果是最外层的方法，则清空要提交的交易，不要提交
     * 如果不是最外层的方法，则不需要负责清空待提交的交易
     */
    public void consumeOnThrow() {
        resource.pop();
        if (resource.getStack() == 0) {
            List<SubmitTxContext> txsToCommit = resource.getTxsToCommit();
            if (!CollectionUtils.isEmpty(txsToCommit)) {
                resource.clearTxsToCommit();
            }
        }
    }

    /**
     * 递增一次递归深度
     */
    public void beforeConsume() {
        resource.push();
    }
}
